﻿#pragma once
#ifndef ___MOD_ANY_HPP
#define ___MOD_ANY_HPP
#include "../config.hpp"
#include <memory>
#include <typeindex>
__MOD_BEGIN
class any
{
public:
	//默认构造函数
	any() : m_tpIndex(std::type_index(typeid(void))) {}
	any(const any& other) : m_ptr(other.clone()), m_tpIndex(other.m_tpIndex) {}
	any(any&& other) : m_ptr(std::move(other.m_ptr)), m_tpIndex(std::move(other.m_tpIndex)) {}
	//通用的右值构造
	template<class T>
	any(T&& t, typename std::enable_if<!std::is_same<any&, T>::value, T>::type* = 0) : m_ptr(new Derived<std::decay<T>::type>(std::forward<T>(t))), m_tpIndex(typeid(std::decay<T>::type))
	{}
	//判断是否为空
	bool is_null()
	{
		return !bool(m_ptr);
	}
	//是否可以类型转换
	template<class T>
	bool is()
	{
		return m_tpIndex == std::type_index(typeid(T));
	}
	//类型转换
	template<class T>
	T& cast()
	{
		if (!is<T>())
		{
			throw std::bad_cast();
		}
		auto ptr = dynamic_cast<Derived<T>*>(m_ptr.get());
		return ptr->m_value;
	}
	any& operator=(const any& other)
	{
		if (m_ptr == other.m_ptr)
		{
			return *this;
		}
		m_ptr = other.clone();
		m_tpIndex = other.m_tpIndex;
		return *this;
	}
private:
	struct Base;
	using BasePtr = std::unique_ptr<Base>;
	//非模板擦除类型
	struct Base
	{
		virtual BasePtr clone() const = 0;
	};
	template<typename T>
	struct Derived : public Base
	{
		template<typename...Args>
		Derived(Args&&...args) : m_value(std::forward<Args>(args)...) {}
		BasePtr clone() const
		{
			return BasePtr(new Derived(m_value));
		}
		T m_value;
	};
	//拷贝使用
	BasePtr clone() const
	{
		if (m_ptr)
		{
			return m_ptr->clone();
		}
		return nullptr;
	}
	BasePtr         m_ptr;      //具体数据
	std::type_index m_tpIndex;  //数据类型
};
__MOD_END
#endif